#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import select
import socket
import sys
import signal
import cPickle
import struct
import argparse

import threading
import os
import base64
import hashlib

import datetime

import RoomManage
import PlayerManage

global s_roomManage
s_roomManage = RoomManage.RoomManage()

#SERVER_HOST = '104.153.103.147' #server
#SERVER_HOST = '192.168.1.33' #home
SERVER_HOST = '172.16.1.221'    #company
CHAT_SERVER_NAME = 'server'
PORT = 3369
MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING = "HTTP/1.1 101 Switching Protocols\r\n" \
    "Upgrade:websocket\r\n" \
    "Connection: Upgrade\r\n" \
    "Sec-WebSocket-Accept: {1}\r\n" \
    "WebSocket-Location: ws://{2}/chat\r\n" \
    "WebSocket-Protocol:chat\r\n\r\n"

# webSocket handshake
def handshake(con):
    try:
        headers = {}
        shake = con.recv(1024)
        
        if not len(shake):
            return False
        
        header, data = shake.split('\r\n\r\n', 1)
        for line in header.split('\r\n')[1:]:
            key, val = line.split(': ', 1)
            headers[key] = val
        
        if 'Sec-WebSocket-Key' not in headers:
            print ('This socket is not websocket, client close.')
            con.close()
            return False

        sec_key = headers['Sec-WebSocket-Key']
        res_key = base64.b64encode(hashlib.sha1(sec_key + MAGIC_STRING).digest())

        print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        str_handshake = HANDSHAKE_STRING.replace('{1}', res_key).replace('{2}', SERVER_HOST + ':' + str(PORT))
        print str_handshake
        con.send(str_handshake)
        return True

    except Exception, e:
        print "error:", e
        return False

# webSocket send
def send_data(con, data):
    if data:
        data = str(data)
    else:
        return False
    token = "\x81"
    length = len(data)
    if length < 126:
        token += struct.pack("B", length)
    elif length <= 0xFFFF:
        token += struct.pack("!BH", 126, length)
    else:
        token += struct.pack("!BQ", 127, length)
    data = '%s%s' % (token, data)
#    print "data: %s" % data
    con.send(data)
    return True

# webSocket receive
def recv_data(con, num):
    print "recving..."
    try:
        all_data = con.recv(num)
        if not len(all_data):
            return False
    except:
        return False
    else:
        code_len = ord(all_data[1]) & 127
        if code_len == 126:
            masks = all_data[4:8]
            data = all_data[8:]
        elif code_len == 127:
            masks = all_data[10:14]
            data = all_data[14:]
        else:
            masks = all_data[2:6]
            data = all_data[6:]
        raw_str = ""
        i = 0
        for d in data:
            raw_str += chr(ord(d) ^ ord(masks[i % 4]))
            i += 1
        return raw_str

def startServer():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    rgConnections = []

    print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    
    s_roomManage.createSomeRooms()
    s_roomManage.createSomeAIs()

    try:
        sock.bind((SERVER_HOST, PORT))
        sock.listen(1000)
    except Exception, e:
        print "error:", e
        sys.exit()

    while True:
        connection, address = sock.accept()
        print "Got connection from ", address
        if handshake(connection):
            print "handshake success"
            newPlayer = PlayerManage.PlayerManage(connection, s_roomManage)
            newPlayer.start()


if __name__ == '__main__':
    startServer()

